package org.ejde.sciencelogs;

import javax.swing.JFrame;

//import org.ejde.periscope.Periscope;

/**
 * This class manages and manipulates an array of formfield objects. formField
 * objects are used to create Java Swing components at run-time based on
 * information extracted from a configuration file.
 * 
 * @author Eric Martin
 * @version 0.1
 */
public class fieldFactory {

	/**
	 * Configuration information
	 */
	private iniParser ini;

	/**
	 * The array of formField objects
	 */
	private formField[] fields;

	/**
	 * Total number of formfield objects
	 */
	public int Ntotfields;

	/**
	 * Containing JFrame
	 */
	public JFrame frame;

	/**
	 * Constructor method for the fieldFactory class
	 * 
	 * @param iniPass
	 *            configuration information
	 */
	public fieldFactory(iniParser iniPass) {
		ini = iniPass;
		construct();
	}

	/**
	 * Build the array of field objects
	 */
	public void construct() {
		this.Ntotfields = this.ini.getFieldCount();
		// System.out.println("TotalFields: "+this.Ntotfields);
		formField[] fields = new formField[this.Ntotfields];
		this.fields = fields;

		// Start Traversing Tree for fields, starting with
		int Fidx = 0;

		// Superfields (Children of the root element)
		int Nsupfields = this.ini.getFieldCount("scilog");

		for (int n = 0; n < Nsupfields; n++) {
			fields[Fidx] = this.makeField(-1, -1, n);
			Fidx++;
		}

		// Panel Field Elements
		int Npanels = this.ini.panelCount();
		for (int n = 0; n < Npanels; n++) {
			int Nfields = this.ini.getFieldCount(n);

			// Make Fields
			for (int i = 0; i < Nfields; i++) {
				fields[Fidx] = this.makeField(n, -1, i);
				Fidx++;
			}

			int Nsubpanels = this.ini.subpanelCount(n);
			for (int m = 0; m < Nsubpanels; m++) {
				int Nsubfields = this.ini.getFieldCount(n, m);
				for (int i = 0; i < Nsubfields; i++) {
					fields[Fidx] = this.makeField(n, m, i);
					Fidx++;
				}
			}

		}

	}

	/**
	 * Creates a field object based on information from the ini object. Each
	 * field has an ID, a tooltip, a type, a label, a hdrout, and a header.
	 * 
	 * Allowed types are: text field, text area and list (dropdown).
	 * 
	 * @param pid
	 *            the panel ID where the field is located
	 * @param spid
	 *            the subpanel ID where the field is located.
	 * @param fid
	 *            the unique ID for the field.
	 * @return formField the resulting field object based on the input file and
	 *         the supplied pid, spid, and fid.
	 */
	private formField makeField(int pid, int spid, int fid) {
		formField field = new formField();

		// Set the panel ID, subpanel ID and field ID
		field.setID(pid, spid, fid);

		// Set tooltip
		String tooltip = this.ini.getFieldAttribute(pid, spid, fid, "tooltip");
		if (tooltip != null) {
			field.setToolTip(tooltip);
		}

		// Set type
		String type = this.ini.getFieldAttribute(pid, spid, fid, "type");
		if (type.equals("text")) {
			field.setType(formField.TEXT_FIELD);
			field.setText(this.ini.getText(this.ini.getField(pid, spid, fid)));

		} else if (type.equals("list")) {
			field.setType(formField.LIST_FIELD);
			String[] options = this.ini.getOptions(pid, spid, fid);
			field.setOptions(options);

		} else if (type.equals("textarea")) {
			field.setType(formField.TEXTAREA_FIELD);
		}

		// Set label
		String label = this.ini.getFieldAttribute(pid, spid, fid, "label");
		field.setLabel(label);

		// Set whether to use flat file output, if enabled
		// the output will be prepended by the header text
		String hdrout = this.ini.getFieldAttribute(pid, spid, fid, "hdrout");
		// If hdrout is not blank
		if (hdrout != null) {
			// If hdrout = 1 set hdrout to true??
			if (hdrout.equals("1")) {
				field.setHdrout(true);
			}
			// If hdrout != 1 set hdrout to false??
			else {
				field.setHdrout(false);
			}
		}
		// TODO
		// Need code to handle if hdrout = null

		// Set header based on the category
		String header = this.ini.getFieldAttribute(pid, spid, fid, "category");
		field.setHeader(header);

		// Set whether or not to clear the field after
		// submitting the event
		String clearonsubmit = this.ini.getFieldAttribute(pid, spid, fid,
				"clearonsubmit");
		if (clearonsubmit != null) {
			if (clearonsubmit.equals("1")) {
				field.setClearOnSubmit(true);
			} else {
				field.setClearOnSubmit(false);
			}
		}

		// Build a Swing object (JLabel, JTextArea,
		// JComboBox) based on the field information
		field.create();

		// Return the field object
		return field;
	}

	/**
	 * Set the frame object for the fieldfactory object
	 * 
	 * @param framepass
	 *            the JFrame object
	 */
	public void setParentFrame(JFrame framepass) {
		this.frame = framepass;
	}

	/**
	 * Get a formField object based on its array index number in the fields
	 * array
	 * 
	 * @param n
	 *            the array index
	 * @return the formField object
	 */
	public formField item(int n) {
		formField field = this.fields[n];
		return field;
	}

	/**
	 * Get an array of formfield objects in the top panel.
	 * 
	 * @return an array of formfield objects
	 */
	public formField[] getTopPanelFields() {
		int fcount = this.ini.getFieldCount("scilog");
		// System.out.println("Top count: "+fcount);
		formField[] tf = new formField[fcount];
		int ffidx = 0;
		for (int n = 0; n < this.Ntotfields; n++) {
			if (this.fields[n].panelID == -1 & this.fields[n].subpanelID == -1) {
				tf[ffidx] = this.fields[n];
				ffidx++;
			}
		}
		return tf;
	}

	/**
	 * Get an array of formfield objects for the specified panel ID.
	 * 
	 * @param pid
	 *            panel id to extract formfield objects.
	 * @return an array of formfield objects
	 */
	public formField[] getPanelFields(int pid) {
		formField[] pf = new formField[this.ini.getFieldCount(pid)];
		int ffidx = 0;
		for (int n = 0; n < this.Ntotfields; n++) {
			if (this.fields[n].panelID == pid & this.fields[n].subpanelID == -1) {
				pf[ffidx] = this.fields[n];
				ffidx++;
			}
		}
		return pf;
	}

	/**
	 * Get an array of formfield objects for the specified panel ID and subpanel
	 * ID.
	 * 
	 * @param pid
	 *            panel id to extract formfield objects.
	 * @param spid
	 *            subpanel id to extract formfield objects.
	 * @return an array of formfield objects
	 */
	public formField[] getSubpanelFields(int pid, int spid) {
		formField[] spf = new formField[this.ini.getFieldCount(pid, spid)];
		int ffidx = 0;
		for (int n = 0; n < this.Ntotfields; n++) {
			if (this.fields[n].panelID == pid
					& this.fields[n].subpanelID == spid) {
				spf[ffidx] = this.fields[n];
				ffidx++;
			}
		}
		return spf;
	}

}
